#coding=utf-8

#资金成本分布计算 
from django.db import models

from shstock.models import *
from stutils import float2dec
            
class OutofRangeError(Exception):
    def __init__(self, r, n):
        self.range = r
        self.data = n
        
    def __str__(self):
        return "%s is out of range:%s"%(str(self.data), str(self.range))
        
class Range(object):

    def __init__(self, s,e,step):
        self.step = step
        self.start = s
        self.end = e
                
        r = []
        point=s
        while point <= e:
            r.append(point)
            point += step
        self.range = r
        
    def get_position(self, n):
        if n > self.end or n < self.start:
            raise OutofRangeError(self.range, n)
            
        #warning:need [:]    
        r = self.range[:]
        r.reverse()
        
        for i in r:
            if n >= i:return i
              
def price_distribution(eds, step=1, tohsl=True):
    eds = list(eds)
    step = Decimal(str(step))
    
    s = eds[0].share
    
    #区间 highest,lowest
    highest = max([e.price.high for e in eds])
    lowest = min([e.price.low for e in eds])
    
    #总换手
    hsls = sum([e.price.hsl for e in eds])
    
    #make range
    if int(highest) == highest: 
        h = highest
    else:
        h = ( int( highest / step ) + 1 ) * step
    l = ( int( lowest / step )  ) * step
    
    rg = Range(l, h , step)
    
    print "start 统计 ..."
    
    result = {}
    for e in eds:
        for dd in e.deal_set.all():
            p = dd.price
            v = dd.volume
            
            point = rg.get_position(p)
            if not result.has_key(point):
                result[point] = v
            else:
                result[point] += v
                
    #volume to 换手率
    #warning: 如果在该时间段内，该股票的流通A股数量有所改变，则不应该将volume转换为换手率
    
    if not tohsl:return result
    
    dates = [e.date.isoformat() for e in eds]
    ts1 = s.get_ts(max(dates))
    ts2 = s.get_ts(min(dates))
    if ts1 != ts2:
        print '在该时间段内，该股票(%s)的流通A股数量有所改变. return volume.'%s.name
        return result
    
    for k in result.keys():
        result[k] = float2dec(result[k]/Decimal(ts1) * 100, 2) 
    
    return result

class NoDealError(Exception):
    def __str__(self):
        return "No Deal data provided."
        
class DealAnalyser(object):
    
    def __init__(self, share, deals):
        if not isinstance(deals, models.query._QuerySet):
            raise TypeError("Deals to be analyed should be django's 'models.query._QuerySet' type")
        if deals.count() == 0:
            raise NoDealError()
            
        self.share = share
        self.qs_deal = deals
    def basicinfo(self):pass
    def price_distribution(self):pass
    
    #一些大单追踪的method
    
if __name__ == '__main__':
    from shstock.models import *

    code = '601600'
    start_date = '2007-10-31'
    end_date = '2007-11-13'

    s = Share.objects.get(code='601600')
    eds = list( Exday.objects.filter(share=s).filter(date__gte=start_date).filter(date__lte=end_date) )
    price_distribution(eds)

        
        
